package vn.edu.ptithcm.pim.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.beans.propertyeditors.CustomCollectionEditor;
import org.springframework.validation.BindException;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;

import vn.edu.ptithcm.pim.common.bean.PaginationObject;
import vn.edu.ptithcm.pim.constant.Constants;
import vn.edu.ptithcm.pim.constant.Functions;
import vn.edu.ptithcm.pim.constant.Paginations;
import vn.edu.ptithcm.pim.constant.UrlConstants;
import vn.edu.ptithcm.pim.dom.EmployeeFunctionInProject;
import vn.edu.ptithcm.pim.dom.EmployeeFunctionInProjectId;
import vn.edu.ptithcm.pim.dom.Project;
import vn.edu.ptithcm.pim.dto.EmployeeFunctionInProjectDto;
import vn.edu.ptithcm.pim.service.DiplomaService;
import vn.edu.ptithcm.pim.service.EmployeeFunctionInProjectService;
import vn.edu.ptithcm.pim.service.EmployeeService;
import vn.edu.ptithcm.pim.service.FunctionService;
import vn.edu.ptithcm.pim.service.LanguageService;
import vn.edu.ptithcm.pim.service.ProjectService;
import vn.edu.ptithcm.pim.service.RankService;
import vn.edu.ptithcm.pim.service.UserService;
import vn.edu.ptithcm.pim.util.ParamUtil;

@SuppressWarnings({ "deprecation", "rawtypes" })
public class MemberController extends SimpleFormController {
	private EmployeeFunctionInProjectService employeeFunctionInProjectService;
	private ProjectService projectService;
	private UserService userService;
	private FunctionService functionService;
	private EmployeeService employeeService;
	private RankService rankService;
	private DiplomaService diplomaService;
	private LanguageService languageService;

	Logger log = Logger.getLogger(MemberController.class);

	public MemberController() {
		super();
		setSessionForm(true);
		setCommandName("members");
		setCommandClass(EmployeeFunctionInProjectDto.class);
		setFormView(UrlConstants.MEMBERS_URL);
		setSuccessView(UrlConstants.MEMBERS_URL);
	}

	@Override
	protected Object formBackingObject(HttpServletRequest request)
			throws Exception {
		EmployeeFunctionInProjectDto members = new EmployeeFunctionInProjectDto();
		return members;
	}

	protected void initBinder(HttpServletRequest request,
			ServletRequestDataBinder binder) {
		binder.registerCustomEditor(List.class, "efip",
				new CustomCollectionEditor(List.class));
	}

	@Override
	protected ModelAndView onSubmit(HttpServletRequest request,
			HttpServletResponse response, Object command, BindException errors)
			throws Exception {
		int pnum = ParamUtil.getInteger(request, "pnum", 0);
		Project project = projectService.findByNumber(pnum);
		String tab = ParamUtil.getString(request, "tab", "");
		String cmd = ParamUtil.getString(request, "cmd", "");

		String searchKey = ParamUtil.getString(request, "searchKey", "");
		long rankId = ParamUtil.getLong(request, "rankId", 0);
		long diplomaId = ParamUtil.getLong(request, "diplomaId", 0);
		String language = ParamUtil.getString(request, "language", "");

		List results = new ArrayList();
		if (project != null) {
			if (tab.equals(Constants.ADD_MEMBERS)) {
				if (cmd.equals(Constants.SEARCH_MEMBERS)) {
					results = employeeService.getMembersForProjectBySearchKey(
							project.getProjectid(), new Long(rankId), new Long(
									diplomaId), language, searchKey);
					request.setAttribute("employees", results);

				} else if (cmd.equals(Constants.ADD_MEMBERS)) {
					EmployeeFunctionInProjectDto informEmployeeFunctionInProjectDto = (EmployeeFunctionInProjectDto) command;
					Iterator<EmployeeFunctionInProject> it = informEmployeeFunctionInProjectDto
							.getEmployeeFunctionInProjects().iterator();

					while (it.hasNext()) {
						EmployeeFunctionInProject efip = it.next();
						if (efip.getFunction().getFunctionid() != null
								&& efip.getEmployee().getEmployeeid() != null) {
							long functionId = efip.getFunction()
									.getFunctionid();
							long employeeId = efip.getEmployee()
									.getEmployeeid();
							if (functionId != 0 && employeeId != 0) {
								efip.setId(new EmployeeFunctionInProjectId(
										functionId, project.getProjectid(),
										employeeId));
								efip.setProject(project);
								employeeFunctionInProjectService.save(efip);
							}
						}
					}
					request.setAttribute("addOK", true);

					results = employeeService.getMembersForProjectBySearchKey(
							project.getProjectid(), new Long(rankId), new Long(
									diplomaId), language, searchKey);
					request.setAttribute("employees", results);

				}
			} else if (tab.equals(Constants.LIST_MEMBERS)) {
				if (cmd.equals(Constants.SEARCH_MEMBERS)) {
					results = employeeFunctionInProjectService.getBySearchKey(
							project.getProjectid(), new Long(rankId), new Long(
									diplomaId), language, searchKey);
					request.setAttribute("efips", results);

				} else if (cmd.equals(Constants.DELETE_MEMBERS)) {
					EmployeeFunctionInProjectDto informEmployeeFunctionInProjectDto = (EmployeeFunctionInProjectDto) command;
					Iterator<EmployeeFunctionInProject> it = informEmployeeFunctionInProjectDto
							.getEmployeeFunctionInProjects().iterator();

					while (it.hasNext()) {
						EmployeeFunctionInProject efip = it.next();
						if (efip.getEmployee().getEmployeeid() != null) {
							employeeFunctionInProjectService
									.removeEmployeeOutOfProject(project
											.getProjectid(), efip.getEmployee()
											.getEmployeeid());
						}
					}
					request.setAttribute("deleteOK", true);
					results = employeeFunctionInProjectService.getBySearchKey(
							project.getProjectid(), new Long(rankId), new Long(
									diplomaId), language, searchKey);
					request.setAttribute("efips", results);

				}
			}
		}
		return showForm(request, response, errors);
	}

	@Override
	protected ModelAndView showForm(HttpServletRequest request,
			HttpServletResponse response, BindException errors)
			throws Exception {
		Map<String, Object> bean = new HashMap<String, Object>();
		if (userService.isSignedIn(request)) {
			String loginName = userService.getCurrentLogin(request);
			int pnum = ParamUtil.getInteger(request, "pnum", 0);
			Project project = projectService.findByNumber(pnum);
			if (project != null) {
				bean.put("user", userService.findByLoginName(loginName));
				bean.put("isSigned", true);
				bean.put("isAdmin", userService.isAdmin(loginName));
				bean.put(Constants.LOGIN_NAME, loginName);
				bean.put(Constants.USER_NAME,
						userService.getUsername(loginName));
				bean.put("functions", functionService.getAll());
				bean.put("ranks", rankService.getAll());
				bean.put("diplomas", diplomaService.getAll());
				bean.put("languages", languageService.getAll());
				bean.put("project", project);
				bean.put("GL", new Long(Functions.GL));

				String tab = ParamUtil.getString(request, "tab", "");
				String searchKey = ParamUtil
						.getString(request, "searchKey", "");
				long rankId = ParamUtil.getLong(request, "rankId", 0);
				long diplomaId = ParamUtil.getLong(request, "diplomaId", 0);
				String language = ParamUtil.getString(request, "language", "");
				List employees = (List) request.getAttribute("employees");
				List efips = (List) request.getAttribute("efips");

				if (tab.equals("addMembers")) {
					if (employees != null) {
						bean.put("employees", employees);
					} else {
						employees = employeeService
								.getMembersForProject(project.getProjectid());
						bean.put("employees", employees);
					}
				}
				if (tab.equals("listMembers")) {
					if (efips != null) {
						bean.put("efips", efips);
					} else {
						efips = employeeFunctionInProjectService
								.findByProjectId(project.getProjectid());
						bean.put("efips", efips);
					}
				}
				bean.put("searchKey", searchKey);
				bean.put("rankId", new Long(rankId));
				bean.put("diplomaId", new Long(diplomaId));
				bean.put("language", language);

				String returnToFullPageURL = ParamUtil.getString(request,
						Constants.RETURN_TO_FULL_PAGE_URL, "");
				if (returnToFullPageURL.isEmpty()) {
					returnToFullPageURL = request.getHeader("referer");
				}
				bean.put(Constants.RETURN_TO_FULL_PAGE_URL, returnToFullPageURL);
				int currentPage = ParamUtil.getInteger(request,
						Paginations.CURRENT_PAGE, 1);
				int pageSize = ParamUtil.getInteger(request,
						Paginations.PAGE_SIZE, Paginations.ITEMS_PER_PAGE);
				int countList = 0;
				if (tab.equals("addMembers")) {
					countList = employees.size();
				} else if (tab.equals("listMembers")) {
					countList = efips.size();
				}
				bean.put("countList", countList);
				PaginationObject paginationProject = null;
				paginationProject = new PaginationObject("members", countList);
				paginationProject.paging(currentPage, pageSize);
				bean.put("paging", paginationProject);
				bean.put("tab", tab);
			}

			request.setAttribute("bean", bean);
		} else {
			String tab = ParamUtil.getString(request, "tab", "");
			int pnum = ParamUtil.getInteger(request, "pnum", 0);
			String redirectLink = UrlConstants.MEMBERS_URL + UrlConstants.HTM
					+ "?pnum=" + pnum + "&tab=" + tab;
			request.getSession().setAttribute("redirectLink", redirectLink);
			response.sendRedirect(UrlConstants.HOME_PAGE_URL + UrlConstants.HTM);
		}
		return super.showForm(request, response, errors);
	}

	public RankService getRankService() {
		return rankService;
	}

	public void setRankService(RankService rankService) {
		this.rankService = rankService;
	}

	public DiplomaService getDiplomaService() {
		return diplomaService;
	}

	public void setDiplomaService(DiplomaService diplomaService) {
		this.diplomaService = diplomaService;
	}

	public EmployeeService getEmployeeService() {
		return employeeService;
	}

	public void setEmployeeService(EmployeeService employeeService) {
		this.employeeService = employeeService;
	}

	public EmployeeFunctionInProjectService getEmployeeFunctionInProjectService() {
		return employeeFunctionInProjectService;
	}

	public void setEmployeeFunctionInProjectService(
			EmployeeFunctionInProjectService employeeFunctionInProjectService) {
		this.employeeFunctionInProjectService = employeeFunctionInProjectService;
	}

	public ProjectService getProjectService() {
		return projectService;
	}

	public void setProjectService(ProjectService projectService) {
		this.projectService = projectService;
	}

	public UserService getUserService() {
		return userService;
	}

	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	public FunctionService getFunctionService() {
		return functionService;
	}

	public void setFunctionService(FunctionService functionService) {
		this.functionService = functionService;
	}

	public LanguageService getLanguageService() {
		return languageService;
	}

	public void setLanguageService(LanguageService languageService) {
		this.languageService = languageService;
	}

}
